package game;

import game.Gamemode.GamemodeManager;
import game.Map.Map;
import game.Player.Player;
import javafx.print.PageLayout;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.*;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.security.CodeSource;

public class Configuration {
    public static Configuration instance;

    private static boolean isFullscreen;
    private static String resolution;            // Display resolution
    private static String volumeMaster;            // Master volume level
    private static String volumeInterface;        // Interface volume level
    private static String volumeMusic;            // Music volume level
    private static String volumeGame;            // Game volume level
    private static String namePlayer;            // Name string of the player
    private static boolean leftHanded;
    private static boolean recoilAnimation;
    private static boolean deathNoticesImages;
    private static boolean chatCommunication;
    private static boolean blood;
    private static boolean shadows;
    private static boolean tacticVision;

    private static String up;                    // Up move key
    private static String down;                    // Down move key
    private static String left;                    // Left move key
    private static String right;                // Right move key
    private static String reload;                // Reload weapon key
    private static String pickUp;                // Pick up key
    private static String primaryWeapon;        // Switch key to primary weapon
    private static String secondaryWeapon;        // Switch key to secondary weapon
    private static String knife;                // Switch key to knife weapon
    private static String alternateWeapon;        // Switch key to the last weapon selected
    private static String store;                // Store key
    private static String plantKey;                // Store key

    /**
     * Constructor of configuration:
     * Load configurtion of "config/save.json" file
     *
     * @throws FileNotFoundException
     * @throws IOException
     * @throws ParseException
     */
    public Configuration() throws FileNotFoundException, IOException, ParseException, URISyntaxException {
        Configuration.instance = this;

        Object obj = getConfigObj();

        JSONObject jsonObject = (JSONObject) obj;

        JSONObject configObject = (JSONObject) jsonObject.get("Configuration");
        JSONObject keyboardConfObject = (JSONObject) jsonObject.get("KeyboardConfiguration");


        resolution = (String) configObject.get("Resolution");
        isFullscreen = (Boolean) configObject.getOrDefault("fullScreen", true);
        volumeMaster = (String) configObject.get("Volume-master");
        volumeInterface = (String) configObject.get("Volume-interface");
        volumeMusic = (String) configObject.get("Volume-music");
        volumeGame = (String) configObject.get("Volume-game");
        namePlayer = (String) configObject.get("Name-player");
        leftHanded = (Boolean) configObject.getOrDefault("leftHanded", false);
        recoilAnimation = (Boolean) configObject.getOrDefault("recoilAnimation", true);
        deathNoticesImages = (Boolean) configObject.getOrDefault("deathNoticesImages", true);
        chatCommunication = (Boolean) configObject.getOrDefault("chatCommunication", true);
        blood = (Boolean) configObject.getOrDefault("blood", true);
        shadows = (Boolean) configObject.getOrDefault("shadows", true);
        tacticVision = (Boolean) configObject.getOrDefault("tacticVision", true);

        up = (String) keyboardConfObject.get("up");
        down = (String) keyboardConfObject.get("down");
        left = (String) keyboardConfObject.get("left");
        right = (String) keyboardConfObject.get("right");
        reload = (String) keyboardConfObject.get("reload");
        plantKey = (String) keyboardConfObject.get("plant");
        pickUp = (String) keyboardConfObject.get("pickUp");
        primaryWeapon = (String) keyboardConfObject.get("primaryWeapon");
        secondaryWeapon = (String) keyboardConfObject.get("secondaryWeapon");
        knife = (String) keyboardConfObject.get("knife");
        alternateWeapon = (String) keyboardConfObject.get("alternateWeapon");
        store = (String) keyboardConfObject.get("store");

    }

    public Object getConfigObj() throws IOException, ParseException, URISyntaxException {
        JSONParser parser = new JSONParser();

        CodeSource codeSource = Configuration.class.getProtectionDomain().getCodeSource();
        File jarFile = new File(codeSource.getLocation().toURI().getPath());
        String jarDir = jarFile.getParentFile().getPath();

        File f = new File(jarDir + "\\save.json");

        Object obj;
        if (!f.exists()) {
            obj = parser.parse(new InputStreamReader(getClass().getClassLoader().
                    getResourceAsStream("config/save.json")));
        } else {
            obj = parser.parse(new FileReader(jarDir + "\\save.json"));
        }
        return obj;
    }

    /**
     * Save a new configuration format
     */
    public void changeConfiguration(String type, String etiqueta, String value) throws IOException, ParseException {
        try {
            JSONParser parser = new JSONParser();


            // Get current dir
            CodeSource codeSource = Configuration.class.getProtectionDomain().getCodeSource();
            File jarFile = new File(codeSource.getLocation().toURI().getPath());
            String jarDir = jarFile.getParentFile().getPath();


            Object obj = getConfigObj();
            JSONObject jsonObject = (JSONObject) obj;
            JSONObject object = (JSONObject) jsonObject.get(type);
            if (etiqueta.equals("leftHanded") || etiqueta.equals("recoilAnimation") || etiqueta.equals("deathNoticesImages")
                    || etiqueta.equals("chatCommunication") || etiqueta.equals("blood") || etiqueta.equals("shadows") || etiqueta.equals("fullScreen")) {
                object.put(etiqueta, Boolean.parseBoolean(value));
            } else {
                object.put(etiqueta, value);
            }


            //TODO: GUARDAR sobre el fichero save.json
            String path = jarDir + "\\save.json";
            try (FileWriter file = new FileWriter(path)) {
                file.write(jsonObject.toString());
            }

        } catch (Exception e) {

        }
    }

    public static Configuration getInstance() {
        return Configuration.instance;
    }


    public static boolean isIsFullscreen() {
        return isFullscreen;
    }

    public static void setIsFullscreen(boolean isFullscreen) {
        Configuration.isFullscreen = isFullscreen;
    }

    public static boolean isLeftHanded() {
        return leftHanded;
    }

    public static void setLeftHanded(boolean leftHanded) {
        Configuration.leftHanded = leftHanded;
    }

    public static boolean isRecoilAnimation() {
        return recoilAnimation;
    }

    public static void setRecoilAnimation(boolean recoilAnimation) {
        Configuration.recoilAnimation = recoilAnimation;
    }

    public static boolean isDeathNoticesImages() {
        return deathNoticesImages;
    }

    public static void setDeathNoticesImages(boolean deathNoticesImages) {
        Configuration.deathNoticesImages = deathNoticesImages;
    }

    public static boolean isChatCommunication() {
        return chatCommunication;
    }

    public static void setChatCommunication(boolean chatCommunication) {
        Configuration.chatCommunication = chatCommunication;
    }

    public static boolean isBlood() {
        return blood;
    }

    public static void setBlood(boolean blood) {
        Configuration.blood = blood;
    }

    public static boolean isShadows() {
        return shadows;
    }

    public static void setShadows(boolean shadows) {
        Configuration.shadows = shadows;
        if (Scene.getInstance() != null && Scene.getInstance().getMap() != null) {
            Scene.getInstance().getMap().updateChunks();
        }
    }

    public static String getAlternateWeapon() {
        return alternateWeapon;
    }

    public static void setAlternateWeapon(String alternateWeapon) {
        Configuration.alternateWeapon = alternateWeapon;
    }

    /**
     * GETTERS & SETTERS
     */


    public static String getVolumeMaster() {
        return volumeMaster;
    }

    public static void setVolumeMaster(String volumeMaster) {
        Configuration.volumeMaster = volumeMaster;
    }

    public static String getNamePlayer() {
        return namePlayer;
    }

    public static void setNamePlayer(String namePlayer) {
        Configuration.namePlayer = namePlayer;
        if (Player.myPlayer != null) {
            Player.myPlayer.setName(namePlayer);
        }
    }

    public static String getVolumeInterface() {
        return volumeInterface;
    }

    public static void setVolumeInterface(String volumeInterface) {
        Configuration.volumeInterface = volumeInterface;
    }

    public static String getVolumeMusic() {
        return volumeMusic;
    }

    public static void setVolumeMusic(String volumeMusic) {
        Configuration.volumeMusic = volumeMusic;
    }

    public static String getVolumeGame() {
        return volumeGame;
    }

    public static boolean getTacticVision() {
        return tacticVision;
    }

    public static void setVolumeGame(String volumeGame) {
        Configuration.volumeGame = volumeGame;
    }

    public static boolean getFullscreen() {
        return isFullscreen;
    }

    public static String getResolution() {
        return resolution;
    }

    public static void setResolution(String resolution) {
        Configuration.resolution = resolution;
    }

    public static String getUp() {
        return up;
    }

    public static void setUp(String up) {
        Configuration.up = up;
    }

    public static String getDown() {
        return down;
    }

    public static void setDown(String down) {
        Configuration.down = down;
    }

    public static String getLeft() {
        return left;
    }

    public static void setLeft(String left) {
        Configuration.left = left;
    }

    public static String getRight() {
        return right;
    }

    public static void setRight(String right) {
        Configuration.right = right;
    }

    public static String getReload() {
        return reload;
    }

    public static void setReload(String reload) {
        Configuration.reload = reload;
    }

    public static String getPlant() {
        return plantKey;
    }

    public static void setPlant(String plant) {
        Configuration.plantKey = plant;
    }

    public static String getPickUp() {
        return pickUp;
    }

    public static void setPickUp(String pickUp) {
        Configuration.pickUp = pickUp;
    }

    public static String getPrimaryWeapon() {
        return primaryWeapon;
    }

    public static void setPrimaryWeapon(String primaryWeapon) {
        Configuration.primaryWeapon = primaryWeapon;
    }

    public static String getSecondaryWeapon() {
        return secondaryWeapon;
    }

    public static void setSecondaryWeapon(String secondaryWeapon) {
        Configuration.secondaryWeapon = secondaryWeapon;
    }

    public static String getKnife() {
        return knife;
    }

    public static void setKnife(String knife) {
        Configuration.knife = knife;
    }

    public static String getalternateWeapon() {
        return alternateWeapon;
    }

    public static void setalternateWeapon(String alternateWeapon) {
        Configuration.alternateWeapon = alternateWeapon;
    }

    public static String getStore() {
        return store;
    }

    public static void setStore(String pause) {
        Configuration.store = pause;
    }

    public static boolean isTacticVision() {
        return tacticVision;
    }

    public static void setTacticVision(boolean tacticVision) {
        Configuration.tacticVision = tacticVision;
    }
}
